package com.atguigu.lease.web.app.service.impl;


import com.atguigu.lease.common.contants.RedisConstants;
import com.atguigu.lease.common.jwt.JwtUtil;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.springmvc.LeaseException;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.service.UserInfoService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.atguigu.lease.web.app.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public void cutomGetCode(String phone) {
        //拼出key
        String key = RedisConstants.APP_LOGIN_PREFIX + phone;
        //查看有没有
        Boolean hasKey = redisTemplate.hasKey(key);
        /**
         * 前端倒计时60秒！60秒后可以重复发送，验证码的有效期是300秒！！
         * 常量1： 总时间300  1  场景2： 间隔时间60 2
         * redisTemplate获取剩余的时间 3
         * if(1-3 > 2){可以发送} else{不可以发送}
         */
        //如果有
        if (hasKey) {
            //查看验证码的剩余时间
            Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            //验证码的有效时间
            Integer appLoginCodeTtlSec = RedisConstants.APP_LOGIN_CODE_TTL_SEC;
            //可以重发验证码的时间
            Integer appLoginCodeResendTimeSec = RedisConstants.APP_LOGIN_CODE_RESEND_TIME_SEC;

            //判断是否过期
            if (appLoginCodeTtlSec - expire < appLoginCodeResendTimeSec){
                throw new LeaseException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
            }
        }

        //如果没有就生成验证码
        String code;
        Random random = new Random();
        code = String.valueOf(random.nextInt(90000) + 100000);
        System.out.println("random = " + code);
        //存储到redis中
        redisTemplate.opsForValue().set(key,code);
    }

    @Override
    public String customLogin(LoginVo loginVo) {
        //获取redis中的验证码
        String code = (String) redisTemplate.opsForValue()
                .get(RedisConstants.APP_LOGIN_PREFIX + loginVo.getPhone());
        System.out.println("code1 = " + code);
        //判断有没有code
        if (code == null) {
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EMPTY);
        }
        //判断code对不对
        if (!loginVo.getCode().equals(code)) {
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }

        //验证码正确，登录或注册
        //根据电话获取用户
        LambdaQueryWrapper<UserInfo> lambdaQueryWrapper
                = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserInfo::getPhone,loginVo.getPhone());
        UserInfo user = userInfoService.getOne(lambdaQueryWrapper);

        //如果没有就注册
        if (user == null) {
            user = new UserInfo();
            user.setPhone(loginVo.getPhone());
            user.setNickname("匿名用户" + loginVo.getPhone().substring(8));
            user.setStatus(BaseStatus.ENABLE);
            user.setAvatarUrl("https://tse3-mm.cn.bing.net/th/id/OIP-C.9G5zpkH0ofiXdX21T" +
                    "jTpfgHaHa?o=7rm=3&rs=1&pid=ImgDetMain&o=7&rm=3");

            userInfoService.save(user);
        }

        //判断有没有被封
        if (user.getStatus().equals(BaseStatus.DISABLE)) {
            throw new LeaseException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
        }

        //返回给前端一个token
        String token = JwtUtil.createToken(user.getId(), user.getPhone());
        return token;
    }

    @Override
    public UserInfoVo customInfo(String accessToken) {
        Integer id = (Integer) JwtUtil.parseToken(accessToken).get("userId");
        final Integer userid = id;
        UserInfo userInfo = userInfoService.getById(id);
        UserInfoVo userInfoVo = new UserInfoVo(
                userInfo.getNickname(),
                userInfo.getAvatarUrl()
        );
        return userInfoVo;
    }


}
